package cn.virens.common.mybatis.dynamic_table.proxy;

import cn.virens.common.util.exception.APIException;
import io.mybatis.provider.EntityTable;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class DynamicTableNameProxyCglib extends DynamicTableNameProxy implements MethodInterceptor {
    private final EntityTable target;

    public static EntityTable buildProxy(EntityTable target) throws APIException {
        var handler = new DynamicTableNameProxyCglib(target);
        var params = new Object[]{target.entityClass()};
        var types = new Class[]{Class.class};

        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(EntityTable.class);
        enhancer.setCallback(handler);

        return (EntityTable) enhancer.create(types, params);
    }

    public DynamicTableNameProxyCglib(EntityTable target) {
        this.target = target;
    }


    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        if (method != null && isMethod(method, "tableName", String.class)) {
            return generateDynamicTableName(target.tableName());
        }

        return method.invoke(target, args);
    }

    @SuppressWarnings("unchecked")
    private static <R> R buildProxy(Class<R> clazz, MethodInterceptor handler) throws Exception {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(handler);

        return (R) enhancer.create();
    }

}
